package controller

import (
	"encoding/json"
	"sale-admin/config/redis"
	"sale-admin/internal/app/web/service/common"
	"sale-admin/internal/app/web/service/coupon"
	"sale-admin/internal/define"
	"strconv"
	"strings"

	"192.168.1.75/go-pkg/response"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type CouponBatch struct{}

// Add 新增优惠码批次
func (CouponBatch) Add(c *gin.Context) {
	var params struct {
		Name                string  `json:"name"`
		Code                string  `json:"code"`
		CodeType            int     `json:"code_type"`
		TotalNum            int64   `json:"total_num"`
		TotalTimes          int64   `json:"total_times"`
		ValidityStartTime   int64   `json:"validity_start_time"`
		ValidityEndTime     int64   `json:"validity_end_time"`
		OrderAmountRequired int     `json:"order_amount_required"`
		OrderAmount         float64 `json:"order_amount"`
		Discount            float64 `json:"discount"`
		Reduce              float64 `json:"reduce"`
		Remark              string  `json:"remark"`
		Desc                string  `json:"desc"`
		AllowGoodsIDs       string  `json:"allow_goods_ids"`
		AllowAreasIDs       string  `json:"allow_area_ids"`
		AllowRobotIDs       string  `json:"allow_robot_ids"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	var allowGoodsIDs, allowAreaIDs, allowRobotIDs []string
	if params.AllowGoodsIDs != "" {
		allowGoodsIDs = strings.Split(params.AllowGoodsIDs, ",")
	}
	if params.AllowAreasIDs != "" {
		allowAreaIDs = strings.Split(params.AllowAreasIDs, ",")
	}
	if params.AllowRobotIDs != "" {
		allowRobotIDs = strings.Split(params.AllowRobotIDs, ",")
	}
	batchID, err := coupon.CouponBatch{}.Add(
		c.Request.Context(),
		params.Name,
		params.Code, params.CodeType,
		params.TotalNum, params.TotalTimes,
		params.ValidityStartTime, params.ValidityEndTime,
		params.OrderAmountRequired, params.OrderAmount,
		params.Reduce, params.Discount,
		params.Remark, params.Desc,
		c.GetString("merchant_id"),
		allowGoodsIDs, allowAreaIDs, allowRobotIDs,
	)
	response.JSON(c, map[string]interface{}{
		"id": batchID,
	}, err)
}

// Update 更新优惠码批次
func (CouponBatch) Update(c *gin.Context) {
	var params struct {
		ID                  string  `json:"id"`
		Name                string  `json:"name"`
		TotalTimes          int64   `json:"total_times"`
		ValidityStartTime   int64   `json:"validity_start_time"`
		ValidityEndTime     int64   `json:"validity_end_time"`
		OrderAmountRequired int     `json:"order_amount_required"`
		OrderAmount         float64 `json:"order_amount"`
		Discount            float64 `json:"discount"`
		Reduce              float64 `json:"reduce"`
		AllowGoodsIDs       string  `json:"allow_goods_ids"`
		AllowAreasIDs       string  `json:"allow_area_ids"`
		AllowRobotIDs       string  `json:"allow_robot_ids"`
		Remark              string  `json:"remark"`
		Desc                string  `json:"desc"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	var allowGoodsIDs, allowAreaIDs, allowRobotIDs []string
	if params.AllowGoodsIDs != "" {
		allowGoodsIDs = strings.Split(params.AllowGoodsIDs, ",")
	}
	if params.AllowAreasIDs != "" {
		allowAreaIDs = strings.Split(params.AllowAreasIDs, ",")
	}
	if params.AllowRobotIDs != "" {
		allowRobotIDs = strings.Split(params.AllowRobotIDs, ",")
	}
	err := coupon.CouponBatch{}.Update(
		c.Request.Context(),
		params.ID, params.Name,
		params.TotalTimes,
		params.ValidityStartTime, params.ValidityEndTime,
		params.OrderAmountRequired, params.OrderAmount,
		params.Reduce, params.Discount,
		params.Remark, params.Desc,
		c.GetString("merchant_id"),
		allowGoodsIDs, allowAreaIDs, allowRobotIDs,
	)
	response.JSON(c, nil, err)
}

// List 优惠码批次列表
func (CouponBatch) List(c *gin.Context) {
	codeType, _ := strconv.Atoi(c.Query("code_type"))
	status, _ := strconv.Atoi(c.Query("status"))
	page, _ := strconv.Atoi(c.Query("page"))
	limit, _ := strconv.Atoi(c.Query("limit"))
	list, total, err := coupon.CouponBatch{}.List(
		c.Request.Context(),
		c.Query("name"),
		codeType,
		status,
		c.GetString("merchant_id"),
		page, limit,
	)
	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, err)
}

// Detail 批次详情
func (CouponBatch) Detail(c *gin.Context) {
	detail, err := coupon.CouponBatch{}.Detail(c.Request.Context(), c.Query("id"))
	response.JSON(c, detail, err)
}

// Options 批次选项
func (CouponBatch) Options(c *gin.Context) {
	codeType, _ := strconv.Atoi(c.Query("code_type"))
	list := coupon.CouponBatch{}.Options(
		c.Request.Context(),
		codeType,
		c.GetString("merchant_id"),
	)
	response.JSON(c, gin.H{
		"list": list,
	}, nil)
}

// AddInventory 增加批次的优惠码库存数量
func (CouponBatch) AddInventory(c *gin.Context) {
	var params struct {
		BatchID string `json:"batch_id"`
		Num     int64  `json:"num"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	err := coupon.CouponBatch{}.AddInventory(c.Request.Context(), c.GetString("merchant_id"), params.BatchID, params.Num)
	response.JSON(c, nil, err)
}

// Invalid 批次 失效
func (CouponBatch) Invalid(c *gin.Context) {
	var params struct {
		ID string `json:"id"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	MerchantID := c.GetString("merchant_id")
	err := coupon.CouponBatch{}.Invalid(c.Request.Context(), MerchantID, params.ID)
	response.JSON(c, nil, err)
}

// GoodsList 用码商品
func (CouponBatch) GoodsList(c *gin.Context) {
	page, _ := strconv.Atoi(c.Query("page"))
	limit, _ := strconv.Atoi(c.Query("limit"))
	list, total, err := coupon.CouponBatch{}.GoodsList(
		c.Request.Context(),
		c.Query("batch_id"),
		c.Query("goods_name"),
		page,
		limit,
	)
	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, err)
}

type CouponCode struct{}

// Check 优惠码验证
// 返回可使用的商品及折扣信息
func (CouponCode) Check(c *gin.Context) {
	var params struct {
		SalesID     string  `json:"SalesID"`
		OrderAmount float64 `json:"OrderAmount"`
		Code        string  `json:"Code"`
		UseCase     int     `json:"UseCase"` // 使用场景，默认为兑换/取货场景
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	deliveringInfo, goodsIDs, reduce, discount, discountAmount, err := coupon.CouponCode{}.Check(
		c.Request.Context(),
		params.SalesID,
		params.OrderAmount,
		params.Code,
		params.UseCase,
		0,
	)
	common.JSONOld(c, map[string]interface{}{
		"DeliveringInfo": deliveringInfo, // 预约的订单出货信息
		"GoodSIDs":       goodsIDs,       // 适用的商品
		"Reduce":         reduce,         // 满减金额
		"Discount":       discount,       // 打折比例
		"DiscountAmount": discountAmount, // 优惠的金额
	}, err)
}

func (CouponCode) Query(c *gin.Context) {
	var params struct {
		SalesID string `json:"SalesID"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	rdb := redis.NewDB()
	data, _ := rdb.Get(c.Request.Context(), define.RedisPickupCode+params.SalesID).Result()
	info := []coupon.DeliveringInfoT{}
	json.Unmarshal([]byte(data), &info)
	common.JSONOld(c, map[string]interface{}{
		"DeliveringInfo": info,       // 预约的订单出货信息
		"GoodSIDs":       []string{}, // 适用的商品
		"Reduce":         0,          // 满减金额
		"Discount":       0,          // 打折比例
		"DiscountAmount": 0,          // 优惠的金额
	}, nil)
}

// 优惠码列表
func (CouponCode) List(c *gin.Context) {
	page, _ := strconv.Atoi(c.Query("page"))
	limit, _ := strconv.Atoi(c.Query("limit"))
	batchID := c.Query("batch_id")
	status := -1
	if statusStr, has := c.GetQuery("status"); has {
		status, _ = strconv.Atoi(statusStr)
	}
	list, total, err := coupon.CouponCode{}.List(
		c.Request.Context(),
		batchID,
		status,
		page,
		limit,
	)
	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, err)
}

// ConsumeLog 优惠码消费记录
func (CouponCode) ConsumeLog(c *gin.Context) {
	startTime, _ := strconv.ParseInt(c.Query("start_time"), 10, 64)
	endTime, _ := strconv.ParseInt(c.Query("end_time"), 10, 64)
	page, _ := strconv.Atoi(c.Query("page"))
	limit, _ := strconv.Atoi(c.Query("limit"))
	list, total, err := coupon.CouponCode{}.ConsumeLog(
		c.Request.Context(),
		c.GetString("merchant_id"),
		c.Query("batch_id"),
		c.Query("code"),
		c.Query("out_trade_no"),
		startTime, endTime,
		page, limit,
	)
	response.JSON(c, gin.H{
		"list":  list,
		"total": total,
	}, err)
}
